package com.litbw.gui;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;

import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import com.litbw.dbbackend.DBContestAdapter;
import com.litbw.dbbackend.DBEntryAdapter;
import com.litbw.dbbackend.DBEventAdapter;
import com.litbw.dbbackend.DBUserAdapter;
import com.litbw.event.Contest;
import com.litbw.event.Contest.Entry;
import com.litbw.event.Event;
import com.litbw.publicobservable.DraftCreatedMessage;
import com.litbw.publicobservable.LoginMessage;
import com.litbw.publicobservable.LogoutMessage;
import com.litbw.publicobservable.RegisterMessage;
import com.litbw.publicobservable.UpdateProfileMessage;
import com.litbw.user.Draft;
import com.litbw.user.User;
import com.litbw.user.UserRole;

/**
 * The RegisterEventPanel. Used for registering in a contest in a specified
 * event.
 * 
 * @author Trygve Stageberg
 */
public class RegisterEventPanel extends AbstractObservablePanel {

	/**
	 * 
	 */
	private static final long serialVersionUID = -2002689045412909037L;

	/**
	 * The default name to use for this panel.
	 */
	private static final String DEF_NAME = "Register for a Contest";

	private final JButton registerEventButton = new JButton(
			"Register for this contest");

	private User theUser;
    //TODO Find event ID
    final int eventID = 1;

    int[] contestIds = null;
    
	private boolean draftCreated = false;

	private JComboBox contestPicker = new JComboBox();
	private JComboBox judgeContestPicker = new JComboBox();

	private JTextArea descText = new JTextArea();
	
	private JPanel centralPanel = new JPanel();
	private JRadioButton attendeeButton = new JRadioButton("Attendee");
	private JRadioButton contestantButton = new JRadioButton("Contestant");
    private JRadioButton judgeButton = new JRadioButton("Judge");
    private JRadioButton organizerButton = new JRadioButton("Organizer");
    private JPanel addEntryPanel = constructAddEntryPanel(eventID);   
    private JPanel addJudgePanel = constructAddJudgePanel(eventID);
    private JPanel addOrganizerPanel = constructAddOrganizerPanel(eventID); 

	protected Draft myDraft;

	/**
	 * Create a new instance of the Registration panel.
	 */
	public RegisterEventPanel() {

		super();
		setLayout(new BorderLayout());
		setName(DEF_NAME);

		myDraft = new Draft();
		addComponents();
	}

	/**
	 * Add the sub components of the RegisterPanel
	 * 
	 * @edited Silvia Chita
	 */
	private void addComponents() {
		
		JPanel rolePanel = new JPanel();

	    ButtonGroup bGroup = new ButtonGroup();
	    bGroup.add(attendeeButton);
	    bGroup.add(contestantButton);
	    bGroup.add(judgeButton);
	    bGroup.add(organizerButton);
	    JLabel chooseRole = new JLabel("Please select a role for this event: ");



	    addEntryPanel.setVisible(true);
	    addJudgePanel.setVisible(true);
	    addOrganizerPanel.setVisible(true);
	    
	    ActionListener buttonListener = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				enablePanels();
			}
	    };
	    
	    attendeeButton.addActionListener(buttonListener);
	    contestantButton.addActionListener(buttonListener);
	    judgeButton.addActionListener(buttonListener);
	    organizerButton.addActionListener(buttonListener);
	    
	    rolePanel.add(chooseRole);
	    rolePanel.add(attendeeButton);
	    rolePanel.add(contestantButton);
	    rolePanel.add(judgeButton);
	    rolePanel.add(organizerButton);
	    
	    add(rolePanel, BorderLayout.NORTH);
	    
	    //Registration button
	    add(registerEventButton, BorderLayout.SOUTH);
	    registerEventButton.addActionListener(new ActionListener() {
		
			@Override
			public void actionPerformed(ActionEvent e) {
				final Contest[] contestList = DBContestAdapter.getContestsForEvent(eventID);
				Contest theContest = new Contest();
        		for (int i = 0; i < contestList.length; i++) {
        			if (contestPicker.getSelectedItem().toString().equals(contestList[i].getDescription())) {
        				theContest = contestList[i];
        				break;
        			}
        		}
        		if (attendeeButton.isSelected()) {
        			//Do nothing
        		} else if (judgeButton.isSelected()) {
        			boolean isAlreadyJudge = false;
        			boolean isContestant = false;
        			for (Contest c : contestList) {
        				if (c.getDescription().equals(judgeContestPicker.getSelectedItem()))
        					theContest = c;
        				if (c.getJudges().contains(theUser))
        					isAlreadyJudge = true;
        			}
        			
        			Entry[] entries = DBEntryAdapter.getEntriesForContest(theContest.getId());
        			if (entries != null) {
        				for (Entry curr : entries)
        					if (curr.getContestant().getEmail().equals(theUser.getEmail()))
        						isContestant = true;
        			}
        			
        			if (judgeContestPicker.getSelectedIndex() == 0) {
        				JOptionPane.showMessageDialog(null,  "Please select a contest to enter!");
        			} else if (isContestant) {
        				JOptionPane.showMessageDialog(null, "You cannot be a judge for a contest you have entered as a contestant!");
        			} else if (isAlreadyJudge) {
        				JOptionPane.showMessageDialog(null, "You are already a judge for that contest!");
        			} else if (!isAlreadyJudge && !isContestant) {
        				//Add a judge to a contest
        				theUser.setRole(UserRole.JUDGE);
        				theContest.addJudge(theUser);
        				DBContestAdapter.updateContest(theContest);
        				DBUserAdapter.updateUser(theUser);
        				JOptionPane.showMessageDialog(null, "Thank you for registering!");
        			}
				} else if (contestantButton.isSelected()) {
					if (contestPicker.getSelectedIndex() == 0) {
        				JOptionPane.showMessageDialog(null,  "Please select a contest to enter!");
					} else {
						if (!draftCreated) {
							JOptionPane.showMessageDialog(null, "Please create a weaving draft before registering!");
						} else {
							if (theUser.getRole() == UserRole.CONTESTANT) {
								if (theContest.getEntries(theUser).isEmpty()) {
									Entry theEntry = new Entry(theUser, myDraft);
									theEntry.setDescription(descText.getText());
									theEntry.addContestId(contestIds[contestPicker.getSelectedIndex()]);
									theContest.addEntry(theEntry);
									theContest.enterContest(theUser, myDraft);
									System.out.println(theEntry.toString());
									DBContestAdapter.updateContest(theContest);
									DBEntryAdapter.addEntry(theEntry);
									DBUserAdapter.updateUser(theUser);
									JOptionPane.showMessageDialog(null, "Thank you for registering!");
								} else {
									JOptionPane.showMessageDialog(null,
													"You already have a entry submitted for this contest!");
								}
							} else {
								theUser.setRole(UserRole.CONTESTANT);
								Entry theEntry = new Entry(theUser, myDraft);
								theEntry.setDescription(descText.getText());
								theEntry.addContestId(contestIds[contestPicker
										.getSelectedIndex()]);
								theContest.addEntry(theEntry);
								theContest.enterContest(theUser, myDraft);
								System.out.println(theEntry.toString());
								DBContestAdapter.updateContest(theContest);
								DBEntryAdapter.addEntry(theEntry);
								DBUserAdapter.updateUser(theUser);
								JOptionPane.showMessageDialog(null,
										"Thank you for registering!");
							}
							
							// Send another login message to the userprofilepanel so that it will update with the new entry.
							RegisterEventPanel.this.setChanged();
							RegisterEventPanel.this.notifyObservers(new UpdateProfileMessage());
							
						}
					}
				}
			}
	    });
	    
	    add(centralPanel, BorderLayout.CENTER);	   
	    enablePanels();
	}

	private void enablePanels() {
		centralPanel.removeAll();
		repaint();
		
		setChanged();
		if (attendeeButton.isSelected()) {
			//do nothing
		} else if (judgeButton.isSelected()) {
			centralPanel.add(addJudgePanel);
			registerEventButton.setEnabled(true);
		} else if (contestantButton.isSelected()) {
			centralPanel.add(addEntryPanel);
			registerEventButton.setEnabled(true);
		} else if (organizerButton.isSelected()) {
			centralPanel.add(addOrganizerPanel);
			registerEventButton.setEnabled(false);
		}
		setChanged();
		
		validate();
		
	}
	
	/**
	 * Helper method for constructing a panel.
	 * 
	 * @param eventID
	 *            The eventID for the event.
	 * @return The panel containing the necessary fields to add a judge.
	 */
	private JPanel constructAddJudgePanel(int eventID) {
		Contest[] contestList = DBContestAdapter.getContestsForEvent(eventID);
		try {
			int test = contestList.length;
		} catch (NullPointerException e) {
			contestList = new Contest[0];
		}

		String[] contestsAvailable = new String[contestList.length + 1];
		contestsAvailable[0] = "";
		for (int i = 1; i < contestsAvailable.length; i++) {
			contestsAvailable[i] = contestList[i - 1].getDescription();
		}

		JPanel myPanel = new JPanel();
		judgeContestPicker = new JComboBox();
		JLabel contestPickerLabel = new JLabel();

		DefaultComboBoxModel options = new DefaultComboBoxModel(contestsAvailable);
		judgeContestPicker.setModel(options);

		contestPickerLabel.setText("Please choose a contest");

		javax.swing.GroupLayout layout = new javax.swing.GroupLayout(myPanel);
		myPanel.setLayout(layout);
		layout.setHorizontalGroup(layout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						javax.swing.GroupLayout.Alignment.TRAILING,
						layout.createSequentialGroup()
								.addContainerGap(85, Short.MAX_VALUE)
								.addComponent(contestPickerLabel)
								.addPreferredGap(
										javax.swing.LayoutStyle.ComponentPlacement.RELATED)
								.addComponent(judgeContestPicker,
										javax.swing.GroupLayout.PREFERRED_SIZE,
										166,
										javax.swing.GroupLayout.PREFERRED_SIZE)
								.addGap(22, 22, 22)));
		layout.setVerticalGroup(layout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						layout.createSequentialGroup()
								.addGap(66, 66, 66)
								.addGroup(
										layout.createParallelGroup(
												javax.swing.GroupLayout.Alignment.BASELINE)
												.addComponent(
														judgeContestPicker,
														javax.swing.GroupLayout.PREFERRED_SIZE,
														javax.swing.GroupLayout.DEFAULT_SIZE,
														javax.swing.GroupLayout.PREFERRED_SIZE)
												.addComponent(
														contestPickerLabel))
								.addContainerGap(214, Short.MAX_VALUE)));
		return myPanel;
	}

	/**
	 * Helper method for constructing a panel.
	 * 
	 * @param eventID The eventID for the event.
	 * @return The panel containing the necessary fields to add a contestant
	 *         entry.
	 */
	private JPanel constructAddEntryPanel(int eventID) {

		Contest[] contestList = DBContestAdapter.getContestsForEvent(eventID);
		try {
			int test = contestList.length;
		} catch (NullPointerException e) {
			contestList = new Contest[0];
		}

		contestIds = new int[contestList.length + 1];
		String[] contestsAvailable = new String[contestList.length + 1];
		contestIds[0] = -1;
		contestsAvailable[0] = "";
		for (int i = 1; i < contestsAvailable.length; i++) {
			contestIds[i] = contestList[i-1].getId();
			contestsAvailable[i] = contestList[i - 1].getDescription();
		}

		DefaultComboBoxModel options = new DefaultComboBoxModel(
				contestsAvailable);
		contestPicker.setModel(options);
		JLabel contestPickerLabel = new JLabel();
		JScrollPane jScrollPane1 = new JScrollPane();
		JLabel descLabel = new JLabel();
		JButton uploadDraft = new JButton();
		uploadDraft.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				myDraft.showDraftMaker(RegisterEventPanel.this);
				//draftCreated = true;
			}
		});
		// uploadDraft.setVisible(false);

		contestPickerLabel.setText("Please choose a contest");

		descText.setColumns(20);
		descText.setRows(5);
		jScrollPane1.setViewportView(descText);

		descLabel.setText("Please provide a short description");

		uploadDraft.setText("Upload Draft");

		JPanel myPanel = new JPanel();
		javax.swing.GroupLayout layout = new javax.swing.GroupLayout(myPanel);
		myPanel.setLayout(layout);
		layout.setHorizontalGroup(layout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						javax.swing.GroupLayout.Alignment.TRAILING,
						layout.createSequentialGroup()
								.addContainerGap(46, Short.MAX_VALUE)
								.addGroup(
										layout.createParallelGroup(
												javax.swing.GroupLayout.Alignment.LEADING)
												.addGroup(
														javax.swing.GroupLayout.Alignment.TRAILING,
														layout.createSequentialGroup()
																.addGroup(
																		layout.createParallelGroup(
																				javax.swing.GroupLayout.Alignment.TRAILING)
																				.addComponent(
																						descLabel)
																				.addComponent(
																						contestPickerLabel))
																.addPreferredGap(
																		javax.swing.LayoutStyle.ComponentPlacement.RELATED))
												.addGroup(
														javax.swing.GroupLayout.Alignment.TRAILING,
														layout.createSequentialGroup()
																.addComponent(
																		uploadDraft)
																.addGap(53, 53,
																		53)))
								.addGroup(
										layout.createParallelGroup(
												javax.swing.GroupLayout.Alignment.LEADING,
												false)
												.addComponent(jScrollPane1)
												.addComponent(
														contestPicker,
														0,
														javax.swing.GroupLayout.DEFAULT_SIZE,
														Short.MAX_VALUE))
								.addGap(22, 22, 22)));
		layout.setVerticalGroup(layout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						layout.createSequentialGroup()
								.addGap(66, 66, 66)
								.addGroup(
										layout.createParallelGroup(
												javax.swing.GroupLayout.Alignment.BASELINE)
												.addComponent(
														contestPicker,
														javax.swing.GroupLayout.PREFERRED_SIZE,
														javax.swing.GroupLayout.DEFAULT_SIZE,
														javax.swing.GroupLayout.PREFERRED_SIZE)
												.addComponent(
														contestPickerLabel))
								.addGap(18, 18, 18)
								.addGroup(
										layout.createParallelGroup(
												javax.swing.GroupLayout.Alignment.LEADING,
												false)
												.addGroup(
														layout.createSequentialGroup()
																.addComponent(
																		descLabel)
																.addPreferredGap(
																		javax.swing.LayoutStyle.ComponentPlacement.RELATED,
																		javax.swing.GroupLayout.DEFAULT_SIZE,
																		Short.MAX_VALUE)
																.addComponent(
																		uploadDraft))
												.addComponent(
														jScrollPane1,
														javax.swing.GroupLayout.PREFERRED_SIZE,
														120,
														javax.swing.GroupLayout.PREFERRED_SIZE))
								.addContainerGap(76, Short.MAX_VALUE)));
		return myPanel;
	}

	/**
	 * Helper method for constructing a panel.
	 * 
	 * @param eventID
	 *            The eventID for the event.
	 * @return The panel containing the necessary fields to add an organizer.
	 * @author Silvia Chita
	 */
	private JPanel constructAddOrganizerPanel(int eventID) {
		Event event = DBEventAdapter.getEvent(eventID);

		JPanel myPanel = new JPanel();
		JLabel verificationLabel = new JLabel(
				"Please enter verification code: ");
		JTextField verificationTextField = new JTextField(25);
		verificationTextField.setEditable(true);
		myPanel.add(verificationLabel);
		myPanel.add(verificationTextField);

		return myPanel;
	}

	@Override
	public void update(final Observable obs, final Object arg) {
		enablePanels();
		if (arg instanceof LoginMessage) {
			System.out.println("User logged in!");
			theUser = ((LoginMessage) arg).getUser();
			myDraft.setUser(theUser);
		}

		if (arg instanceof LogoutMessage) {
			final LogoutMessage msg = (LogoutMessage) arg;

			theUser = null;
		}

		// Check for EventDetailMessages
		if (arg instanceof RegisterMessage) {

			final RegisterMessage msg = (RegisterMessage) arg;
			final Event theEvent = msg.getEvent();

			// TODO: remove after debug.
			// System.out.println("RegisterPanel recieved signal: " +
			// msg.getSignal());
			// System.out.println("      EventData: " + theEvent);

			// Decipher signal
			switch (msg.getSignal()) {
			case UPDATE:

				break;
			case CLEAR:

				break;
			}
		}
		
		if (arg instanceof DraftCreatedMessage) {
			System.out.println("draft created!");
			draftCreated = true;
			
		}

	}

}
